package com.code.train.service.impl;


import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.code.train.autoconfig.template.SmsTemplate;
import com.code.train.domain.Member;
import com.code.train.domain.MemberExample;
import com.code.train.enums.redis.MemberEnum;
import com.code.train.exception.BusinessException;
import com.code.train.exception.BusinessExceptionEnum;
import com.code.train.mapper.MemberMapper;
import com.code.train.req.MemberLoginReq;
import com.code.train.req.MemberRegisterReq;
import com.code.train.req.MemberSendCodeReq;
import com.code.train.resp.MemberLoginResp;
import com.code.train.service.MemberService;
import com.code.train.util.JwtUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.Objects;

/**
 * MemberServiceImpl
 *
 * @param
 * @author 南汉卿
 * @return
 * @date 2025/8/3 16:12
 */
@Service
@Slf4j
public class MemberServiceImpl implements MemberService {

    @Value("${train.member.login.redis.timeoutM}")
    public  Long timeout;

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    RedisTemplate<String,String> redisTemplate;

    @Autowired
    SmsTemplate template;

    @Override
    public Long count() {
        log.info(JwtUtils.TOKEN_SECRET+"-------"+JwtUtils.TOKEN_TIME_OUT);
        return memberMapper.countByExample(null);
    }

    @Override
    public Long register(MemberRegisterReq registerReq) {
        //获取手机号
        String mobile = registerReq.getMobile();
        //判断手机号是否存在
        MemberExample memberExample = new MemberExample();
        memberExample.createCriteria().andMobileEqualTo(mobile);
        List<Member> members = memberMapper.selectByExample(memberExample);
        if(CollUtil.isNotEmpty(members)){
            throw  new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_EXIST);
        }
        //封装数据
        Member member = new Member();
        member.setId(System.currentTimeMillis());
        member.setMobile(mobile);
        //插入数据
        memberMapper.insertSelective(member);
        return member.getId();
    }

    /**
     * 发送短信验证码
     * @param sendCodeReq
     */
    @Override
    public void sendCode(MemberSendCodeReq sendCodeReq) {
        //获取手机号
        String mobile = sendCodeReq.getMobile();

        //获取实体类
        Member memberDB = getMemberByMobile(mobile);

        //判断手机号是否存在
        if(Objects.isNull(memberDB)){
            log.info("用户不存在，注册");
            Member member = new Member();
            //封装数据
            member.setId(System.currentTimeMillis());
            member.setMobile(mobile);
            //插入数据
            memberMapper.insertSelective(member);
        }

        //生成短信验证码
        //String code = RandomStringUtils.randomNumeric(6);
        String code = "123456";
        log.info("生成短信验证码: {}",code);
        //生成短信记录表 手机号 验证码 验证状态 生成时间 使用时间 有效期 主要是为了后期进行统计 和 防止恶意请求

        //对接短信通道 发送短信";
        //2、调用template对象，发送手机短信
//        template.sendSms(mobile,code);
        //3、将验证码存入到redis
        redisTemplate.opsForValue().set(MemberEnum.MEMBER_CHECK_CODE +mobile,code, Duration.ofMinutes(timeout));
    }

    /**
     * 登录
     * @param loginReq
     * @return MemberLoginResp
     */
    @Override
    public MemberLoginResp login(MemberLoginReq loginReq) {
        //获取手机号
        String mobile = loginReq.getMobile();

        //获取实体类
        Member memberDB = getMemberByMobile(mobile);

        //判断手机号是否存在
        if(Objects.isNull(memberDB)){
           throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_NOT_EXIST);
        }

        //获取验证码，判断验证码是否正确
        String code = redisTemplate.opsForValue().get(MemberEnum.MEMBER_CHECK_CODE +mobile);
        log.info("验证码为: {}",code);
        if(ObjectUtil.isNull(code)){
            throw new BusinessException(BusinessExceptionEnum.MEMBER_SEND_CODE_NOT_EXIST);
        }
//        redisTemplate.delete("CHECK_CODE_" + mobile);
        if(!code.equals(loginReq.getCode())){
            throw new BusinessException(BusinessExceptionEnum.MEMBER_SEND_CODE_ERROR);
        }

        //生成token，封装
        MemberLoginResp memberLoginResp = BeanUtil.copyProperties(memberDB, MemberLoginResp.class);
        memberLoginResp.setToken(JwtUtils.getToken(BeanUtil.beanToMap(memberLoginResp)));
        return memberLoginResp;
    }

    /**
     * 生成图形验证码
     * @param sendCodeReq
     */
    @Override
    public void sendPictureCode(MemberSendCodeReq sendCodeReq, HttpServletResponse response){
        try {
            LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(299, 100);
            String code = lineCaptcha.getCode();
            redisTemplate.opsForValue().set(MemberEnum.MEMBER_PICTURE_CHECK_CODE+sendCodeReq.getMobile(),code,Duration.ofMinutes(5));
            lineCaptcha.write(response.getOutputStream());
        } catch (IOException e) {
            throw new BusinessException(BusinessExceptionEnum.MEMBER_SEND_CODE_PICTURE_ERROR);
        }
    }


    private Member getMemberByMobile(String mobile){
        //判断手机号是否存在
        MemberExample memberExample = new MemberExample();
        memberExample.createCriteria().andMobileEqualTo(mobile);
        List<Member> members = memberMapper.selectByExample(memberExample);
        if(CollUtil.isEmpty(members)){
            return null;
        }else{
            return  members.get(0);
        }
    }
}
